package com.quwan.common.service.impl;

import com.quwan.common.constant.OssConstant;
import com.quwan.common.exception.QuWanException;
import com.quwan.common.result.OssResultDTO;
import com.quwan.common.service.FileUploadService;
import com.quwan.common.service.oss.IObjectStorageStrategy;
import com.quwan.config.yml.OssConfig;
import com.quwan.utils.FIleCheckUtils;
import com.quwan.utils.OSSFileUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author lt
 * @Date 2021/12/1 11:31 上午
 */
@Service
public class FileUploadServiceImpl implements FileUploadService, BeanPostProcessor {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OssConfig ossConfig;

    private IObjectStorageStrategy objectStorageStrategy;
    @Override
    public List<OssResultDTO> uploadFileOss(HttpServletRequest request, String type) throws IOException {
        if (StringUtils.isEmpty(type)) {
            throw new QuWanException("文件类型为空");
        }
        List<OssResultDTO> resultDTOList = new ArrayList();
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        // 获取上传的文件
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Iterator it = multipartRequest.getFileNames();
            if (!it.hasNext()) {
                throw new QuWanException("文件名称不能空");
            }
            try {
                objectStorageStrategy.createClient();
                while (it.hasNext()) {
                    String fieldName = (String) it.next();
                    MultipartFile file = multipartRequest.getFile(fieldName);
                    // 上传文件校验
                    File changeFile = FIleCheckUtils.fileCheck(type, file);
                    String originalFileName = file.getOriginalFilename();
                    // 文件后缀名
                    String suffix = originalFileName.substring(originalFileName.lastIndexOf("."));
                    // 新名称
                    String newFileName = FIleCheckUtils.getUUIDName(suffix);
                    // 云服务器上存储文件的相对路径
                    String filePath = OssConstant.getFilePath(type);
                    String serverPath = ossConfig.getHostname() + "/" + filePath;
                    // 绝对路径
                    String absolutePath = serverPath + newFileName;
                    // 相对路径
                    String relativePath = filePath + newFileName;
                    logger.info("开始上传文件：" + originalFileName);
                    Long startTime = System.currentTimeMillis();
                    boolean uploadStatus;
                    if (changeFile != null) {
                        uploadStatus = objectStorageStrategy.storeLocalFile(changeFile, relativePath);
                        changeFile.delete();
                    } else {
                        uploadStatus = objectStorageStrategy.storeFile(file, relativePath);
                    }
                    logger.info("上传文件：" + originalFileName + "耗时：" + (System.currentTimeMillis() - startTime) + " 返回值：" + uploadStatus);
                    OssResultDTO ossResultDTO = new OssResultDTO();
                    if (uploadStatus) {
                        ossResultDTO.setFieldName(fieldName);
                        ossResultDTO.setOriginalName(originalFileName);
                        ossResultDTO.setNewName(newFileName);
                        ossResultDTO.setSuffix(suffix);
                        ossResultDTO.setRelativePath(relativePath);
                        ossResultDTO.setAbsPath(absolutePath);
                        resultDTOList.add(ossResultDTO);
                    } else {
                        throw new QuWanException("上传到阿里云失败");
                    }
                }
            } finally {
                objectStorageStrategy.closeClient();
            }
        }
        return resultDTOList;
    }


    @Override
    public boolean removeFileOss(List<String> filePaths) {
        List<String> relativePaths = new ArrayList();
        try {
            if (!filePaths.isEmpty()) {
                for (String path : filePaths) {
                    if (StringUtils.isNotEmpty(path)) {
                        relativePaths.add(path.replaceAll(ossConfig.getHostname() + "/", ""));
                    }
                }
            }
            if (!relativePaths.isEmpty()) {
                objectStorageStrategy.createClient();
                objectStorageStrategy.removeFileListByKeyList(relativePaths);
            }
        } catch (Exception e) {
            throw new QuWanException(e.getMessage());
        } finally {
            objectStorageStrategy.closeClient();
        }
        return false;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (null != objectStorageStrategy) {
            return bean;
        }
        String accessKeyId = ossConfig.getAccessKeyId();
        String accessKeySecret = ossConfig.getSecretKey();
        String endpoint = ossConfig.getEndpoint();
        String bucketName = ossConfig.getBucketName();
        objectStorageStrategy = new OSSFileUtil(accessKeyId, accessKeySecret, endpoint, bucketName);
        return bean;
    }
}
